# v1.5.0

# 功能测试

## EdfLoadBalancer 慢启动

使用 examples/codes/slow-start-sample 配置和 server 测试，使用以下客户端统计

```go
package main

import (
	"flag"
	"fmt"
	"net/http"
)

var port int
var total int

func init() {
	flag.IntVar(&port, "port", 2046, "server port")
	flag.IntVar(&total, "total", 100, "total requests")
	flag.Parse()
}

func main() {

	var count = map[string]int{}

	for i := 0; i < total; i++ {
		resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d", port))
		if err != nil {
			fmt.Println(err)
			continue
		}
		var remote []byte = make([]byte, 100)
		resp.Body.Read(remote)
		_, exist := count[string(remote)]
		if exist {
			count[string(remote)] += 1
		} else {
			count[string(remote)] = 1
		}
	}

	for k, v := range count {
		fmt.Println("port: ", k, "count: ", v)
	}
}
```

### 启动 server 和 mosn

启动多个HTTP server，并指定每个HTTP server的端口（端口号`8080`、`8081`、`8082`已经配置在了`config.json`）

```Bash
go run server.go -port=${port}
```


使用配置来运行MOSN
```Bash
./mosn start -c examples/codes/slow-start-sample/config.json
```

### 使用 client 验证

```Bash
$ go run client.go -port=2046
port:  8080 count:  17
port:  8081 count:  33
port:  8082 count:  50
```

最开始，所有的服务器都在相同的时间启动，此时慢启动没有发生作用

杀掉端口号为`8082`的服务器，并在一个健康检查周期后启动。在服务器启动后的第一个健康检查周期后，再次执行相同的命令，可以发现端口号为`8082`的服务器的权重在逐渐增加，直至与配置权重相同

```Bash
$ go run client.go -port=2046
port:  8080 count:  25
port:  8081 count:  50
port:  8082 count:  25

$ go run client.go -port=2046
port:  8080 count:  21
port:  8081 count:  42
port:  8082 count:  37

$ go run client.go -port=2046
port:  8080 count:  18
port:  8081 count:  36
port:  8082 count:  46

$ go run client.go -port=2046
port:  8080 count:  17
port:  8081 count:  33
port:  8082 count:  50
```

## 支持集群独占连接池

通过配置多个 cluster 来支持对同一 ip:port 建立多条连接

mosn配置文件 `./mosn_config.json`
```json
{
	"servers": [
		{
			"default_log_path": "stdout",
			"routers": [
				{
					"router_config_name": "route-2046",
					"virtual_hosts": [
						{
							"name": "test-1",
							"domains": ["example-1.com:2046"],
							"routers": [{
									"match": {"prefix": "/"},
									"route": {"cluster_name": "cluster-1"}
								}]
						},
						{
							"name": "test-2",
							"domains": ["example-2.com:2046"],
							"routers": [{
									"match": {"prefix": "/"},
									"route": {"cluster_name": "cluster-2"}
								}]
						}
					]
				}
			],
			"listeners": [
				{
					"name": "localhost-2046",
					"address": "127.0.0.1:2046",
					"bind_port": true,
					"filter_chains": [{
							"filters": [
								{
									"type": "proxy",
									"config": {
										"downstream_protocol": "Http1",
										"router_config_name": "route-2046"
									}
								}
							]
						}]
				}
			]
		}
	],
	"cluster_manager": {
		"clusters": [
			{
				"name": "cluster-1",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes": 32768,
				"hosts": [
					{"address": "127.0.0.1:12345"}
				],
				"cluster_pool_enable": true
			},
			{
				"name": "cluster-2",
				"type": "SIMPLE",
				"lb_type": "LB_RANDOM",
				"max_request_per_conn": 1024,
				"conn_buffer_limit_bytes": 32768,
				"hosts": [
					{"address": "127.0.0.1:12345"}
				],
				"cluster_pool_enable": true
			}
		]
	},
	"admin": {
		"address": {
			"socket_address": {
				"address": "0.0.0.0",
				"port_value": 34901
			}
		}
	}
}
```

go 服务端代码 `./server.go`
```go
package main

import (
	"flag"
	"fmt"
	"net/http"
)

var port int

func init() {
	flag.IntVar(&port, "port", 12345, "server port")
	flag.Parse()
}

var count int64 = 0

func handle(res http.ResponseWriter, req *http.Request) {
	fmt.Fprintln(res, fmt.Sprintf("Host: %s, addr: %s", req.Host, req.RemoteAddr))
}

func main() {
	server := http.Server{
		Addr: fmt.Sprintf("0.0.0.0:%d", port),
	}

	http.HandleFunc("/", handle)
	server.ListenAndServe()
}
```

go 服务端会返回对端连接的 Host 和 addr，用来判断是否建立多条连接

首先需要在 hosts 文件中新增域名，使其指向网关，此处域名与 mosn 配置中 domains 对应，以下为 mac 中的修改命令
```Bash
$ sudo vim /etc/hosts
...
127.0.0.1       example-1.com
127.0.0.1       example-2.com
$ sudo killall -HUP mDNSResponder
```

随后启动 mosn 和 go server，并使用 curl 分别访问 example-1.com，example-2.com，可以观察到服务端对端的 addr 并不相同
```Bash
$ ./mosn start -c ./mosn_config.json
$ go run server.go
$ curl example-1.com:2046
Host: example-1.com:2046, addr: 127.0.0.1:63293
$ curl example-2.com:2046
Host: example-2.com:2046, addr: 127.0.0.1:63298
```

如果关闭 mosn cluster 配置中 "cluster_pool_enable" 选项，则两次访问返回的 addr 信息相同
```Bash
$ curl example-1.com:2046
Host: example-1.com:2046, addr: 127.0.0.1:63316
$ curl example-2.com:2046
Host: example-2.com:2046, addr: 127.0.0.1:63316
```

# 基准测试

+ 使用[sofaload](https://github.com/antJack/sofaload)在本地搭建简单的性能测试

## v1.5.0测试结果

```Bash
sofaload -D 10 --qps=2000 -c 200 -t 16 -p sofarpc sofarpc://127.0.0.1:12200
starting benchmark...
Application protocol: sofarpc

finished in 10.00s, 2000.00 req/s, 2.41MB/s
requests: 20000 total, 20000 started, 20000 done, 20000 succeeded, 0 failed, 0 errored, 0 timeout
sofaRPC status codes: 
	20000 success, 0 error, 0 server exception, 0 unknown
	0 server threadpool busy, 0 error comm, 0 no processor, 0 timeout
	0 client send error, 0 codec exception, 0 connection closed, 0 server serial exception
	0 server deserial exception
traffic: 24.11MB (25280000) total, 390.63KB (400000) headers (space savings 0.00%), 23.73MB (24880000) data
                     min         max         mean         sd        +/- sd
time for request:      131us      7.65ms       270us       276us    96.10%
time for connect:        4us        32us        16us         7us    62.00%
req/s           :       9.50       10.60       10.00        0.41    80.00%

  Latency  Distribution
   50%        212us
   75%        287us
   90%        407us
   95%        506us
   99%       1.02ms
```

## v1.4.0测试结果

```Bash
sofaload -D 10 --qps=2000 -c 200 -t 16 -p sofarpc sofarpc://127.0.0.1:12200
starting benchmark...
Application protocol: sofarpc

finished in 10.00s, 2000.00 req/s, 2.41MB/s
requests: 20000 total, 20004 started, 20000 done, 20000 succeeded, 0 failed, 0 errored, 0 timeout
sofaRPC status codes: 
	20000 success, 0 error, 0 server exception, 0 unknown
	0 server threadpool busy, 0 error comm, 0 no processor, 0 timeout
	0 client send error, 0 codec exception, 0 connection closed, 0 server serial exception
	0 server deserial exception
traffic: 24.11MB (25280000) total, 390.63KB (400000) headers (space savings 0.00%), 23.73MB (24880000) data
                     min         max         mean         sd        +/- sd
time for request:      135us     10.17ms       297us       466us    98.40%
time for connect:        4us        28us        13us         5us    62.00%
req/s           :       9.50       10.50       10.00        0.41    75.50%

  Latency  Distribution
   50%        222us
   75%        305us
   90%        431us
   95%        529us
   99%       1.06ms
```
